~ function(){
    var LS = {};
    LS.UI = function(){
    
        // Constants
        var POPUP_HEIGHT_PER_FRAME = 110;
        var POPUP_HEIGHT_TOTAL = 2200;
        var _ICON_STATE = {
            SUCCESS: 1,
            ERROR: 2,
            INFO: 3,
            WARNING: 4,
            QUESTION: 5
        }
        
        // Elements
        var tbInReplyTo = $('#in_reply_to');
        var tbStatus = $('#status');
        var board = $('#topNotice');
        var icon = $('#notice-icon');
        var textArea = $('#notice-text');
        var counterWrapper = $('#postCounter');
        var countArea = $('#text-counter-count');
        var popupClickMe = $('.clickmepop');
        var timeline = $("#timeline");
        var latestStatus = $('#lastUpdate');
        var updateCounter = $('#updateCounter');
        var msgBox = $('#tkyou');
        var autoSwitch = $('#autoSwitch');
        
        // Variables
        var lastReadItem;
        var title = document.title;
        var unreadCount = 0;
        var popupTarget;
        var autoUpdate = true;
        
        // Settings
        var username = $('#screen-name').val();
        var rtFormat = $('#rt-format').val();
        
        var _updateStatus = function(statusText, inReplyTo, cursorPos){
            tbStatus.val(statusText);
            tbInReplyTo.val(inReplyTo);
            if (cursorPos !== null) {
                tbStatus.attr({
                    selectionStart: cursorPos,
                    selectionEnd: cursorPos
                });
            }
            tbStatus.focus();
            _updateTextCounter();
        }
        
        var _updateNotice = function(text, state, showTime, duration){
            state = state || LS.UI.ICON_STATE.SUCCESS;
            showTime = showTime || 3000;
            duration = duration || 300;
            textArea.html(text);
            icon.attr('class', 't-notice-ico-' + state);
            board.slideDown(duration, function(){
                setTimeout(function(){
                    board.slideUp(duration, function(){
                        board.hide();
                    });
                }, showTime);
            });
        }
        
        var _updateTitle = function(){
            document.title = unreadCount ? "(" + unreadCount + ") " + title : title;
        }
        
        var _updateTextCounter = function(){
            var len = tbStatus.val().length;
            if (len <= 140) {
                countArea.html(140 - len);
                counterWrapper.css('color', '#B3B3B3');
            }
            else {
                countArea.html(-(len - 140));
                counterWrapper.css('color', '#FF3300');
            }
        }
        
        var _updateLatest = function(text){
            latestStatus.attr('title', text);
            latestStatus.find('span').html(text);
        }
        
        var _showPopup = function(e){
            popupTarget = $(e.target);
            popupClickMe.css({
                left: (popupTarget.offset().left - popupClickMe.width()) + 'px',
                top: (popupTarget.offset().top - popupClickMe.height() + 20) + 'px',
                backgroundPosition: '0 0'
            }).show().find('a').hide();
            var y = 0;
            var t = setInterval(function(){
                if (y <= -(POPUP_HEIGHT_TOTAL - POPUP_HEIGHT_PER_FRAME)) {
                    clearInterval(t);
                    popupClickMe.find('a').show();
                }
                popupClickMe.css('background-position', '0 ' + y + 'px');
                y -= POPUP_HEIGHT_PER_FRAME;
            }, 30);
        }
        
        var _getNewTimeLine = function(){
            if (!autoUpdate) 
                return;
            lastReadItem = timeline.find('li:not(.new):not(.by_me):first');
            $.ajax({
                url: "ajax/home_time_line",
                type: 'POST',
                data: {
                    since_id: lastReadItem.attr('id')
                },
                success: function(html){
                    if (!html) 
                        return;

                    /*var currentScrollTop = $(window).scrollTop();
                    var footerOffsetTop = $('#footer').offset().top;*/
                    
                    var stack = [];
                    $(html).find('li').each(function(index){
                        stack.push($(this));
                    });
                    while (stack.length > 0) {
                        var item = stack.pop().prependTo(timeline).hide();
                        if ($.trim(item.find('.username').html()) !== username) {
                            item.addClass('unread');
                            unreadCount++;
                        }
                    }
                    if (unreadCount > 0) {
                        _updateTitle();
                        msgBox.slideDown().find('span').html(unreadCount);
                    }
                    
                    /*var scrollOffset = $('#footer').offset().top - footerOffsetTop;
                    $(window).scrollTop(currentScrollTop + scrollOffset);*/
                }
            });
        }
        
        var _resetHome = function(){
            popupClickMe.hide();
            $('#more-popup').hide();
        }
        
        var _replyClick = function(e){
            var li = $(this).closest("li");
            _updateStatus('@' + li.find('.username').html() + ' ', li.attr('id'));
            e.preventDefault();
        }
        
        var _clickmeClick = function(e){
            _showPopup(e);
            e.preventDefault();
        }
        
        var _moreClick = function(e) {
            e.preventDefault();
            var popup = $('#more-popup');
            popupTarget = $(e.target);
            popup.css({
                left: (popupTarget.offset().left - 22) + 'px',
                top: (popupTarget.offset().top - popup.height()) + 'px'
            }).fadeIn(200, function() {
                popup.find('ul').effect('bounce', { direction: 'right', times:5, distance: 15 }, 75);
            });
        }
        
        var _statusKeypress = function(e){
            setTimeout(function(){
                _updateTextCounter();
            }, 0);
        }
        
        var _switchClick = function(){
            var handle = $(this).find('.handle');
            autoUpdate = !autoUpdate;
            handle.animate({
                left: (autoUpdate ? 0 : 17) + 'px'
            }, 100);
        }
        
        var _quoteClick = function(e){
            var PATTERN = rtFormat;
            var li = popupTarget.closest("li");
            var user = $.trim(li.find('.username').text());
            var content = $.trim(li.find('.content').text());
            var text = PATTERN.replace('{user}', user).replace('{content}', content);
            var pos = text.indexOf('{cursor}');
            text = text.replace('{cursor}', '');
            _updateStatus(text, '', pos);
        }
        
        var _retweetClick = function(e){
            var li = popupTarget.closest("li");
            $.ajax({
                type: 'POST',
                url: 'ajax/retweet',
                data: {
                    status_id: li.attr('id')
                },
                success: function(){
                    _updateNotice('转推成功！');
                },
                error: function(){
                    _updateNotice('转推失败，你可以已经转发过此推。', LS.UI.ICON_STATE.ERROR);
                }
            })
        }
        
        var _translateClick = function(e) {
            var li = popupTarget.closest('li');
            if (li.find('.translated').length > 0) {
                return;
            }
            var textToTranslate = $.trim(li.find('.content').text());
            var div = $('<div></div>').addClass('translated').appendTo(li);
            var p = $('<p style="text-align:center"><img src="/images/loading.gif" src="loading" /></p>').appendTo(div);
            google.language.translate(textToTranslate, '', 'zh-cn', function(result) {
                if (!result.error) {
                    if (result.translation !== textToTranslate) {
                        div.html(result.translation);
                    } else {
                        div.remove();
                    }
                } else {
                    div.remove();
                }
            });
        }
        
        var _favClick = function(e){
            var self = $(this);
            self.removeClass('fav').addClass('faved');
            $.ajax({
                url: "ajax/add_fav",
                type: 'POST',
                data: {
                    id: self.closest('li').attr('id')
                },
                error: function(){
                    self.removeClass('faved').addClass('fav');
                    _updateNotice('添加收藏失败', _ICON_STATE.ERROR);
                }
            });
            e.preventDefault();
        }
        
        var _favedClick = function(e){
            var self = $(this);
            self.removeClass('faved').addClass('fav');
            $.ajax({
                url: "ajax/del_fav",
                type: 'POST',
                data: {
                    id: self.closest('li').attr('id')
                },
                error: function(){
                    self.removeClass('fav').addClass('faved');
                    _updateNotice('删除收藏失败', _ICON_STATE.ERROR);
                }
            });
            e.preventDefault();
        }
        
        var _deleteClick = function(e){
            e.preventDefault();
            var self = $(this);
            var li = self.closest('li');
            if (!confirm('确定删除？')) 
                return;
            $.ajax({
                url: "ajax/del_status",
                type: 'POST',
                data: {
                    id: li.attr('id')
                },
                success: function(){
                    _updateNotice('成功删除');
                    li.css("background-color", "#FFC").fadeOut(500, function(){
                        li.remove();
                    });
                }
            });
        }
        
        var _nextHomeTimeLineClick = function(e){
            e.preventDefault();
            var self = $(this);
            if (!self.hasClass('more-enable')) {
                return;
            }
            self.addClass('more-loading').removeClass('more-enable').html('');
            $.ajax({
                url: "ajax/home_time_line",
                cache: false,
                type: 'POST',
                data: {
                    max_id: $('#timeline li:last').attr('id')
                },
                success: function(html){
                    $('#timeline').find('li:last').addClass('item-solid-border');
                    array = $(html).find('li');
                    for (var i = 1; i < array.length; i++) 
                        $(array[i]).appendTo('#timeline');
                    self.removeClass('more-loading').addClass('more-enable').html('更多');
                },
                error: function(){
                    _updateNotice('失败鸟');
                    self.removeClass('more-loading').addClass('more-enable').html('更多');
                }
            });
        }
        
        var _updateStatusClick = function(e){
            $.ajax({
                url: "ajax/update",
                type: 'POST',
                data: {
                    status: $('#status').val(),
                    in_reply_to: $('#in_reply_to').val()
                },
                success: function(html){
                    var li = $(html).find('li').addClass('by_me').prependTo("#timeline");
                    tbStatus.val('');
                    tbInReplyTo.val('');
                    _updateLatest(li.find('.content').text());
                    _updateTextCounter();
                    _updateNotice('更新成功');
                    updateCounter.html(parseInt(updateCounter.html()) + 1);
                }
            });
            e.preventDefault();
        }
        
        var _msgboxClick = function(){
            msgBox.slideUp(function(){
                var scrollTop = $(window).scrollTop();
                var tempOffsetTop = $('#footer').offset().top;
                timeline.find('.unread:last').addClass('item-solid-border').end().find('.unread').removeClass('unread').show();
                
                msgBox.hide();
                
                var scrollOffset = $('#footer').offset().top - tempOffsetTop;
                $(window).scrollTop(scrollTop + scrollOffset);
                
                unreadCount = 0;
                _updateTitle();
            });
        }
        
        var _homeLinkClick = function(e){
            $.ajax({
                url: "ajax/home_time_line",
                cache: false,
                type: 'POST',
                success: function(html){
                    timeline.html(html);
                }
            });
            e.preventDefault();
        }
		
        return {
            ICON_STATE: _ICON_STATE,
            /*
             updateStatus: _updateStatus,
             updateNotice: _updateNotice,
             updateTitle: _updateTitle,
             updateTextCounter: _updateTextCounter,
             updateLatestStatus: _updateLatest,
             showPopup: _showPopup,
             resetHome: _resetHome,
             */
            getNewTimeline: _getNewTimeLine,
            
            clickmeClick: _clickmeClick,
            replyClick: _replyClick,
            quoteClick: _quoteClick,
            retweetClick: _retweetClick,
            favClick: _favClick,
            favedClick: _favedClick,
            deleteClick: _deleteClick,
            statusKeypress: _statusKeypress,
            switchClick: _switchClick,
            nextHomeTimeLineClick: _nextHomeTimeLineClick,
            updateStatusClick: _updateStatusClick,
            msgboxClick: _msgboxClick,
            homeLinkClick: _homeLinkClick,
            resetHome: _resetHome,
            moreClick: _moreClick,
            translateClick: _translateClick
        }
        
    }();
	
    window['LS'] = LS;
    
    // Common handlers
    $(function(){
        // $('.clickme').live('click', LS.UI.clickmeClick);
        $('.clickme').live('click', LS.UI.moreClick);
        $('#more-popup a').click(function(e) {
            e.preventDefault();
        });
        $('#status').keypress(LS.UI.statusKeypress);
        $('.fav').live('click', LS.UI.favClick);
        $('.faved').live('click', LS.UI.favedClick);
        $('#retweet').click(LS.UI.retweetClick);
        $('#translate').click(LS.UI.translateClick);
        $('.delete').live('click', LS.UI.deleteClick);
    });
}();
